]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/utilscmn.cpp
fixed wxStrrchr(s, '\0') bug, added const and non const versions of wxStrchr, wxStrrc...
[wxWidgets.git] / src / common / utilscmn.cpp
index c5e8204954558a1c5cc87e7a2649beb1e9cb7e31..05e1c3f123dfa74ea923208f247b20ad26de5a1e 100644 (file)
 // Created:     29/01/98
 // RCS-ID:      $Id$
 // Copyright:   (c) 1998 Julian Smart
 // Created:     29/01/98
 // RCS-ID:      $Id$
 // Copyright:   (c) 1998 Julian Smart
-// Licence:    wxWindows license
+// Licence:     wxWindows license
 /////////////////////////////////////////////////////////////////////////////
 
 /////////////////////////////////////////////////////////////////////////////
 
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
 #ifdef __GNUG__
 #ifdef __GNUG__
-#pragma implementation "utils.h"
+    #pragma implementation "utils.h"
 #endif
 
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 #ifdef __BORLANDC__
 #endif
 
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 #ifdef __BORLANDC__
-#pragma hdrstop
+    #pragma hdrstop
 #endif
 
 #ifndef WX_PRECOMP
 #endif
 
 #ifndef WX_PRECOMP
-#include "wx/defs.h"
-#include "wx/utils.h"
-#include "wx/window.h"
-#include "wx/menu.h"
-#include "wx/frame.h"
-#include "wx/msgdlg.h"
-#include "wx/textdlg.h"
-#endif
-
-#if wxUSE_IOSTREAMH
-#include <iostream.h>
-#include <fstream.h>
-#else
-#include <iostream>
-#include <fstream>
-#  ifdef _MSC_VER
-      using namespace std;
-#  endif
+    #include "wx/defs.h"
+    #include "wx/string.h"
+    #include "wx/utils.h"
+    #include "wx/intl.h"
+    #include "wx/log.h"
+
+    #if wxUSE_GUI
+        #include "wx/app.h"
+        #include "wx/window.h"
+        #include "wx/frame.h"
+        #include "wx/menu.h"
+        #include "wx/msgdlg.h"
+        #include "wx/textdlg.h"
+        #include "wx/textctrl.h"    // for wxTE_PASSWORD
+        #if wxUSE_ACCEL
+            #include "wx/menuitem.h"
+            #include "wx/accel.h"
+        #endif // wxUSE_ACCEL
+    #endif // wxUSE_GUI
+#endif // WX_PRECOMP
+
+#ifndef __WIN16__
+#include "wx/process.h"
+#include "wx/txtstrm.h"
 #endif
 
 #include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #endif
 
 #include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+
 #if !defined(__WATCOMC__)
 #if !defined(__WATCOMC__)
-#if !(defined(_MSC_VER) && (_MSC_VER > 800))
-#include <errno.h>
-#endif
+    #if !(defined(_MSC_VER) && (_MSC_VER > 800))
+        #include <errno.h>
+    #endif
 #endif
 #endif
+
+#if wxUSE_GUI
+    #include "wx/colordlg.h"
+    #include "wx/fontdlg.h"
+    #include "wx/notebook.h"
+    #include "wx/frame.h"
+    #include "wx/statusbr.h"
+#endif // wxUSE_GUI
+
 #include <time.h>
 #include <time.h>
+
 #ifndef __MWERKS__
 #ifndef __MWERKS__
-#include <sys/types.h>
-#include <sys/stat.h>
+    #include <sys/types.h>
+    #include <sys/stat.h>
 #endif
 
 #endif
 
-// Pattern matching code.
-// Yes, this path is deliberate (for Borland compilation)
-#ifdef wx_mac /* MATTHEW: [5] Mac doesn't like paths with "/" */
-#include "glob.inc"
-#else
-#include "../common/glob.inc"
+#ifdef __SALFORDC__
+    #include <clib.h>
 #endif
 
 #ifdef __WXMSW__
 #endif
 
 #ifdef __WXMSW__
-#include "windows.h"
+    #include "wx/msw/private.h"
 #endif
 
 #endif
 
-#define _MAXPATHLEN 500
+// ----------------------------------------------------------------------------
+// common data
+// ----------------------------------------------------------------------------
+
+#if WXWIN_COMPATIBILITY_2_2
+    const wxChar *wxInternalErrorStr = wxT("wxWindows Internal Error");
+    const wxChar *wxFatalErrorStr = wxT("wxWindows Fatal Error");
+#endif // WXWIN_COMPATIBILITY_2_2
+
+// ----------------------------------------------------------------------------
+// function protoypes
+// ----------------------------------------------------------------------------
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// string functions
+// ----------------------------------------------------------------------------
+
+#if defined(__WXMAC__) && !defined(__DARWIN__)
+int strcasecmp(const char *str_1, const char *str_2)
+{
+  register char c1, c2;
+  do {
+    c1 = tolower(*str_1++);
+    c2 = tolower(*str_2++);
+  } while ( c1 && (c1 == c2) );
+
+  return c1 - c2;
+}
+
+int strncasecmp(const char *str_1, const char *str_2, size_t maxchar)
+{
+
+  register char c1, c2;
+  while( maxchar--)
+  {
+    c1 = tolower(*str_1++);
+    c2 = tolower(*str_2++);
 
 
-extern char *wxBuffer;
+    if ( !c1 || c1!=c2 )
+                  return c1 - c2;
 
 
-#ifdef __VMS__
+  } ;
+
+  return 0 ;
+
+}
+#endif // __WXMAC__ && !__DARWIN__
+
+#if defined( __VMS__ ) && ( __VMS_VER < 70000000 )
 // we have no strI functions under VMS, therefore I have implemented
 // an inefficient but portable version: convert copies of strings to lowercase
 // and then use the normal comparison
 // we have no strI functions under VMS, therefore I have implemented
 // an inefficient but portable version: convert copies of strings to lowercase
 // and then use the normal comparison
@@ -93,7 +162,7 @@ int strcasecmp(const char *str_1, const char *str_2)
   myLowerString(temp1);
   myLowerString(temp2);
 
   myLowerString(temp1);
   myLowerString(temp2);
 
-  int result = strcmp(temp1,temp2);
+  int result = wxStrcmp(temp1,temp2);
   delete[] temp1;
   delete[] temp2;
 
   delete[] temp1;
   delete[] temp2;
 
@@ -115,9 +184,9 @@ int strncasecmp(const char *str_1, const char *str_2, size_t maxchar)
 
   return(result);
 }
 
   return(result);
 }
-#endif
+#endif // __VMS__
 
 
-#ifdef __WINDOWS__
+#if defined(__WINDOWS__) && !defined(__WXMICROWIN__)
 
 #ifndef __GNUWIN32__
 #ifndef __MWERKS__
 
 #ifndef __GNUWIN32__
 #ifndef __MWERKS__
@@ -129,15 +198,13 @@ int strncasecmp(const char *str_1, const char *str_2, size_t maxchar)
 #endif
 #endif
 
 #endif
 #endif
 
-#ifdef _MSC_VER
-#pragma warning (disable : 4245)
-#endif
+#else
 
 
-#ifdef _MSC_VER
-#pragma warning (default : 4245)
+#ifdef __EMX__
+#define strcasecmp stricmp
+#define strncasecmp strnicmp
 #endif
 
 #endif
 
-#else
 // This declaration is missing in SunOS!
 // (Yes, I know it is NOT ANSI-C but its in BSD libc)
 #if defined(__xlC) || defined(__AIX__) || defined(__GNUG__)
 // This declaration is missing in SunOS!
 // (Yes, I know it is NOT ANSI-C but its in BSD libc)
 #if defined(__xlC) || defined(__AIX__) || defined(__GNUG__)
@@ -147,17 +214,26 @@ extern "C"
   int strncasecmp (const char *, const char *, size_t);
 }
 #endif
   int strncasecmp (const char *, const char *, size_t);
 }
 #endif
-#endif                         /* __WXMSW__ */
+#endif  /* __WXMSW__ */
+
+#ifdef __WXPM__
+#define strcasecmp stricmp
+#define strncasecmp strnicmp
+#endif
 
 
+#ifdef __WATCOMC__
+#define strcasecmp stricmp
+#define strncasecmp strnicmp
+#endif
 
 
-char *
-copystring (const char *s)
+wxChar *
+copystring (const wxChar *s)
 {
 {
-  if (s == NULL) s = "";
-  size_t len = strlen (s) + 1;
+  if (s == NULL) s = wxT("");
+  size_t len = wxStrlen (s) + 1;
 
 
-  char *news = new char[len];
-  memcpy (news, s, len);       // Should be the fastest
+  wxChar *news = new wxChar[len];
+  memcpy (news, s, len * sizeof(wxChar));    // Should be the fastest
 
   return news;
 }
 
   return news;
 }
@@ -165,7 +241,7 @@ copystring (const char *s)
 // Id generation
 static long wxCurrentId = 100;
 
 // Id generation
 static long wxCurrentId = 100;
 
-long 
+long
 wxNewId (void)
 {
   return wxCurrentId++;
 wxNewId (void)
 {
   return wxCurrentId++;
@@ -174,102 +250,100 @@ wxNewId (void)
 long
 wxGetCurrentId(void) { return wxCurrentId; }
 
 long
 wxGetCurrentId(void) { return wxCurrentId; }
 
-void 
+void
 wxRegisterId (long id)
 {
   if (id >= wxCurrentId)
     wxCurrentId = id + 1;
 }
 
 wxRegisterId (long id)
 {
   if (id >= wxCurrentId)
     wxCurrentId = id + 1;
 }
 
-void 
-StringToFloat (char *s, float *number)
+void
+StringToFloat (const wxChar *s, float *number)
 {
   if (s && *s && number)
 {
   if (s && *s && number)
-    *number = (float) strtod (s, (char **) NULL);
+    *number = (float) wxStrtod (s, (wxChar **) NULL);
 }
 
 }
 
-void 
-StringToDouble (char *s, double *number)
+void
+StringToDouble (const wxChar *s, double *number)
 {
   if (s && *s && number)
 {
   if (s && *s && number)
-    *number = strtod (s, (char **) NULL);
+    *number = wxStrtod (s, (wxChar **) NULL);
 }
 
 }
 
-char *
-FloatToString (float number, const char *fmt)
+wxChar *
+FloatToString (float number, const wxChar *fmt)
 {
 {
-  static char buf[256];
+  static wxChar buf[256];
 
 
-//  sprintf (buf, "%.2f", number);
-  sprintf (buf, fmt, number);
+  wxSprintf (buf, fmt, number);
   return buf;
 }
 
   return buf;
 }
 
-char *
-DoubleToString (double number, const char *fmt)
+wxChar *
+DoubleToString (double number, const wxChar *fmt)
 {
 {
-  static char buf[256];
+  static wxChar buf[256];
 
 
-  sprintf (buf, fmt, number);
+  wxSprintf (buf, fmt, number);
   return buf;
 }
 
   return buf;
 }
 
-void 
-StringToInt (char *s, int *number)
+void
+StringToInt (const wxChar *s, int *number)
 {
   if (s && *s && number)
 {
   if (s && *s && number)
-    *number = (int) strtol (s, (char **) NULL, 10);
+    *number = (int) wxStrtol (s, (wxChar **) NULL, 10);
 }
 
 }
 
-void 
-StringToLong (char *s, long *number)
+void
+StringToLong (const wxChar *s, long *number)
 {
   if (s && *s && number)
 {
   if (s && *s && number)
-    *number = strtol (s, (char **) NULL, 10);
+    *number = wxStrtol (s, (wxChar **) NULL, 10);
 }
 
 }
 
-char *
+wxChar *
 IntToString (int number)
 {
 IntToString (int number)
 {
-  static char buf[20];
+  static wxChar buf[20];
 
 
-  sprintf (buf, "%d", number);
+  wxSprintf (buf, wxT("%d"), number);
   return buf;
 }
 
   return buf;
 }
 
-char *
+wxChar *
 LongToString (long number)
 {
 LongToString (long number)
 {
-  static char buf[20];
+  static wxChar buf[20];
 
 
-  sprintf (buf, "%ld", number);
+  wxSprintf (buf, wxT("%ld"), number);
   return buf;
 }
 
 // Array used in DecToHex conversion routine.
   return buf;
 }
 
 // Array used in DecToHex conversion routine.
-static char hexArray[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B',
-  'C', 'D', 'E', 'F' };
+static wxChar hexArray[] = wxT("0123456789ABCDEF");
 
 // Convert 2-digit hex number to decimal
 int wxHexToDec(const wxString& buf)
 {
   int firstDigit, secondDigit;
 
 // Convert 2-digit hex number to decimal
 int wxHexToDec(const wxString& buf)
 {
   int firstDigit, secondDigit;
-  
-  if (buf.GetChar(0) >= 'A')
-    firstDigit = buf.GetChar(0) - 'A' + 10;
+
+  if (buf.GetChar(0) >= wxT('A'))
+    firstDigit = buf.GetChar(0) - wxT('A') + 10;
   else
   else
-    firstDigit = buf.GetChar(0) - '0';
+    firstDigit = buf.GetChar(0) - wxT('0');
 
 
-  if (buf.GetChar(1) >= 'A')
-    secondDigit = buf.GetChar(1) - 'A' + 10;
+  if (buf.GetChar(1) >= wxT('A'))
+    secondDigit = buf.GetChar(1) - wxT('A') + 10;
   else
   else
-    secondDigit = buf.GetChar(1) - '0';
-    
-  return firstDigit * 16 + secondDigit;
+    secondDigit = buf.GetChar(1) - wxT('0');
+
+  return (firstDigit & 0xF) * 16 + (secondDigit & 0xF );
 }
 
 // Convert decimal integer to 2-character hex string
 }
 
 // Convert decimal integer to 2-character hex string
-void wxDecToHex(int dec, char *buf)
+void wxDecToHex(int dec, wxChar *buf)
 {
   int firstDigit = (int)(dec/16.0);
   int secondDigit = (int)(dec - (firstDigit*16.0));
 {
   int firstDigit = (int)(dec/16.0);
   int secondDigit = (int)(dec - (firstDigit*16.0));
@@ -281,14 +355,14 @@ void wxDecToHex(int dec, char *buf)
 // Convert decimal integer to 2-character hex string
 wxString wxDecToHex(int dec)
 {
 // Convert decimal integer to 2-character hex string
 wxString wxDecToHex(int dec)
 {
-    char buf[3];
+    wxChar buf[3];
     wxDecToHex(dec, buf);
     return wxString(buf);
 }
 
 // Match a string INDEPENDENT OF CASE
     wxDecToHex(dec, buf);
     return wxString(buf);
 }
 
 // Match a string INDEPENDENT OF CASE
-bool 
-StringMatch (char *str1, char *str2, bool subString, bool exact)
+bool
+StringMatch (const char *str1, const char *str2, bool subString, bool exact)
 {
   if (str1 == NULL || str2 == NULL)
     return FALSE;
 {
   if (str1 == NULL || str2 == NULL)
     return FALSE;
@@ -304,15 +378,15 @@ StringMatch (char *str1, char *str2, bool subString, bool exact)
       // Search for str1 in str2
       // Slow .... but acceptable for short strings
       for (i = 0; i <= len2 - len1; i++)
       // Search for str1 in str2
       // Slow .... but acceptable for short strings
       for (i = 0; i <= len2 - len1; i++)
-       {
-         if (strncasecmp (str1, str2 + i, len1) == 0)
-           return TRUE;
-       }
+        {
+          if (strncasecmp (str1, str2 + i, len1) == 0)
+            return TRUE;
+        }
     }
   else if (exact)
     {
       if (strcasecmp (str1, str2) == 0)
     }
   else if (exact)
     {
       if (strcasecmp (str1, str2) == 0)
-       return TRUE;
+        return TRUE;
     }
   else
     {
     }
   else
     {
@@ -320,7 +394,7 @@ StringMatch (char *str1, char *str2, bool subString, bool exact)
       int len2 = strlen (str2);
 
       if (strncasecmp (str1, str2, wxMin (len1, len2)) == 0)
       int len2 = strlen (str2);
 
       if (strncasecmp (str1, str2, wxMin (len1, len2)) == 0)
-       return TRUE;
+        return TRUE;
     }
 
   return FALSE;
     }
 
   return FALSE;
@@ -328,88 +402,80 @@ StringMatch (char *str1, char *str2, bool subString, bool exact)
 
 // Return the current date/time
 // [volatile]
 
 // Return the current date/time
 // [volatile]
-wxString wxNow( void )
+wxString wxNow()
 {
   time_t now = time((time_t *) NULL);
 {
   time_t now = time((time_t *) NULL);
-  char *date = ctime(&now); 
+  char *date = ctime(&now);
   date[24] = '\0';
   return wxString(date);
 }
 
   date[24] = '\0';
   return wxString(date);
 }
 
-/* Get Full RFC822 style email address */
-bool
-wxGetEmailAddress (char *address, int maxSize)
-{
-  char host[65];
-  char user[65];
+#if wxUSE_GUI
 
 
-  if (wxGetHostName(host, 64) == FALSE)
-    return FALSE;
-  if (wxGetUserId(user, 64) == FALSE)
-    return FALSE;
+#if wxUSE_MENUS
 
 
-  char tmp[130];
-  strcpy(tmp, user);
-  strcat(tmp, "@");
-  strcat(tmp, host);
+// ----------------------------------------------------------------------------
+// Menu accelerators related functions
+// ----------------------------------------------------------------------------
 
 
-  strncpy(address, tmp, maxSize - 1);
-  address[maxSize-1] = '\0';
-  return TRUE;
-}
+wxChar *wxStripMenuCodes(const wxChar *in, wxChar *out)
+{
+    wxString s = wxMenuItem::GetLabelFromText(in);
+    if ( out )
+    {
+        // go smash their buffer if it's not big enough - I love char * params
+        memcpy(out, s.c_str(), s.length() * sizeof(wxChar));
+    }
+    else
+    {
+        out = copystring(s);
+    }
 
 
-/*
- * Strip out any menu codes
- */
+    return out;
+}
 
 
-char *wxStripMenuCodes (char *in, char *out)
+wxString wxStripMenuCodes(const wxString& in)
 {
 {
-  if (!in)
-    return (char *) NULL;
-    
-  if (!out)
-    out = copystring(in);
+    wxString out;
+
+    size_t len = in.length();
+    out.reserve(len);
 
 
-  char *tmpOut = out;
-  
-  while (*in)
+    for ( size_t n = 0; n < len; n++ )
     {
     {
-      if (*in == '&')
-       {
-         // Check && -> &, &x -> x
-         if (*++in == '&')
-           *out++ = *in++;
-       }
-      else if (*in == '\t')
-       {
-          // Remove all stuff after \t in X mode, and let the stuff as is
-          // in Windows mode.
-          // Accelerators are handled in wx_item.cc for Motif, and are not
-          // YET supported in XView
-         break;
-       }
-      else
-       *out++ = *in++;
-    }                          // while
-
-  *out = '\0';
-
-  return tmpOut;
-}
-
-wxString wxStripMenuCodes(const wxString& str)
-{
-    char *buf = new char[str.Length() + 1];
-    wxStripMenuCodes((char*) (const char*) str, buf);
-    wxString str1(buf);
-    delete[] buf;
-    return str1;
+        wxChar ch = in[n];
+        if ( ch == _T('&') )
+        {
+            // skip it, it is used to introduce the accel char (or to quote
+            // itself in which case it should still be skipped): note that it
+            // can't be the last character of the string
+            if ( ++n == len )
+            {
+                wxLogDebug(_T("Invalid menu string '%s'"), in.c_str());
+            }
+            else
+            {
+                // use the next char instead
+                ch = in[n];
+            }
+        }
+        else if ( ch == _T('\t') )
+        {
+            // everything after TAB is accel string, exit the loop
+            break;
+        }
+
+        out += ch;
+    }
+
+    return out;
 }
 
 }
 
-/*
- * Window search functions
- *
- */
+#endif // wxUSE_MENUS
+
+// ----------------------------------------------------------------------------
+// Window search functions
+// ----------------------------------------------------------------------------
 
 /*
  * If parent is non-NULL, look through children for a label or title
 
 /*
  * If parent is non-NULL, look through children for a label or title
@@ -417,54 +483,12 @@ wxString wxStripMenuCodes(const wxString& str)
  *
  */
 
  *
  */
 
-static wxWindow *wxFindWindowByLabel1 (const wxString& title, wxWindow * parent);
-
 wxWindow *
 wxFindWindowByLabel (const wxString& title, wxWindow * parent)
 {
 wxWindow *
 wxFindWindowByLabel (const wxString& title, wxWindow * parent)
 {
-  if (parent)
-    {
-      return wxFindWindowByLabel1 (title, parent);
-    }
-  else
-    {
-      for (wxNode * node = wxTopLevelWindows.First (); node; node = node->Next ())
-       {
-         wxWindow *win = (wxWindow *) node->Data ();
-         wxWindow *retwin = wxFindWindowByLabel1 (title, win);
-         if (retwin)
-           return retwin;
-       }                       // for()
-
-    }
-  return (wxWindow *) NULL;
+    return wxWindow::FindWindowByLabel( title, parent );
 }
 
 }
 
-// Recursive
-static wxWindow *
-wxFindWindowByLabel1 (const wxString& title, wxWindow * parent)
-{
-  if (parent)
-    {
-      if (parent->GetLabel() == title)
-               return parent;
-    }
-
-  if (parent)
-    {
-      for (wxNode * node = parent->GetChildren().First (); node; node = node->Next ())
-       {
-         wxWindow *win = (wxWindow *) node->Data ();
-         wxWindow *retwin = wxFindWindowByLabel1 (title, win);
-         if (retwin)
-           return retwin;
-       }                       // for()
-
-    }
-
-  return (wxWindow *) NULL;                    // Not found
-
-}
 
 /*
  * If parent is non-NULL, look through children for a name
 
 /*
  * If parent is non-NULL, look through children for a name
@@ -472,113 +496,118 @@ wxFindWindowByLabel1 (const wxString& title, wxWindow * parent)
  *
  */
 
  *
  */
 
-static wxWindow *wxFindWindowByName1 (const wxString& title, wxWindow * parent);
-
 wxWindow *
 wxWindow *
-wxFindWindowByName (const wxString& title, wxWindow * parent)
+wxFindWindowByName (const wxString& name, wxWindow * parent)
 {
 {
-  if (parent)
-    {
-      return wxFindWindowByName1 (title, parent);
-    }
-  else
-    {
-      for (wxNode * node = wxTopLevelWindows.First (); node; node = node->Next ())
-       {
-         wxWindow *win = (wxWindow *) node->Data ();
-         wxWindow *retwin = wxFindWindowByName1 (title, win);
-         if (retwin)
-           return retwin;
-       }                       // for()
+    return wxWindow::FindWindowByName( name, parent );
+}
 
 
-    }
-  // Failed? Try by label instead.
-  return wxFindWindowByLabel(title, parent);
+// Returns menu item id or -1 if none.
+int
+wxFindMenuItemId (wxFrame * frame, const wxString& menuString, const wxString& itemString)
+{
+#if wxUSE_MENUS
+  wxMenuBar *menuBar = frame->GetMenuBar ();
+  if ( menuBar )
+      return menuBar->FindMenuItem (menuString, itemString);
+#endif // wxUSE_MENUS
+
+  return -1;
 }
 
 }
 
-// Recursive
-static wxWindow *
-wxFindWindowByName1 (const wxString& title, wxWindow * parent)
+// Try to find the deepest child that contains 'pt'.
+// We go backwards, to try to allow for controls that are spacially
+// within other controls, but are still siblings (e.g. buttons within
+// static boxes). Static boxes are likely to be created _before_ controls
+// that sit inside them.
+wxWindow* wxFindWindowAtPoint(wxWindow* win, const wxPoint& pt)
 {
 {
-  if (parent)
+    if (!win->IsShown())
+        return NULL;
+
+    // Hack for wxNotebook case: at least in wxGTK, all pages
+    // claim to be shown, so we must only deal with the selected one.
+#if wxUSE_NOTEBOOK
+    if (win->IsKindOf(CLASSINFO(wxNotebook)))
     {
     {
-       if ( parent->GetName() == title )
-                       return parent;
+      wxNotebook* nb = (wxNotebook*) win;
+      int sel = nb->GetSelection();
+      if (sel >= 0)
+      {
+        wxWindow* child = nb->GetPage(sel);
+        wxWindow* foundWin = wxFindWindowAtPoint(child, pt);
+        if (foundWin)
+           return foundWin;
+      }
     }
     }
+#endif
 
 
-  if (parent)
+    /* Doesn't work
+    // Frame case
+    else if (win->IsKindOf(CLASSINFO(wxFrame)))
     {
     {
-      for (wxNode * node = parent->GetChildren().First (); node; node = node->Next ())
-       {
-         wxWindow *win = (wxWindow *) node->Data ();
-         wxWindow *retwin = wxFindWindowByName1 (title, win);
-         if (retwin)
-           return retwin;
-       }                       // for()
-
+      // Pseudo-children that may not be mentioned in the child list
+      wxWindowList extraChildren;
+      wxFrame* frame = (wxFrame*) win;
+      if (frame->GetStatusBar())
+        extraChildren.Append(frame->GetStatusBar());
+      if (frame->GetToolBar())
+        extraChildren.Append(frame->GetToolBar());
+
+      wxNode* node = extraChildren.First();
+      while (node)
+      {
+          wxWindow* child = (wxWindow*) node->Data();
+          wxWindow* foundWin = wxFindWindowAtPoint(child, pt);
+          if (foundWin)
+            return foundWin;
+          node = node->Next();
+      }
     }
     }
+    */
 
 
-  return (wxWindow *) NULL;                    // Not found
-
-}
-
-// Returns menu item id or -1 if none.
-int 
-wxFindMenuItemId (wxFrame * frame, const wxString& menuString, const wxString& itemString)
-{
-  wxMenuBar *menuBar = frame->GetMenuBar ();
-  if (!menuBar)
-    return -1;
-  return menuBar->FindMenuItem (menuString, itemString);
-}
+    wxNode* node = win->GetChildren().Last();
+    while (node)
+    {
+        wxWindow* child = (wxWindow*) node->Data();
+        wxWindow* foundWin = wxFindWindowAtPoint(child, pt);
+        if (foundWin)
+          return foundWin;
+        node = node->Previous();
+    }
 
 
-/*
- * wxDebugStreamBuf
- */
-#if !defined(_WINDLL)
-wxDebugStreamBuf::wxDebugStreamBuf(void)
-{
-       // <iostream> usage doesn't need this, and i have no idea how to simulate it.
-#if wxUSE_IOSTREAMH
-       if (allocate())
-         setp(base(),ebuf());
-#endif
-}
+    wxPoint pos = win->GetPosition();
+    wxSize sz = win->GetSize();
+    if (win->GetParent())
+    {
+        pos = win->GetParent()->ClientToScreen(pos);
+    }
 
 
-int wxDebugStreamBuf::overflow(int WXUNUSED(i))
-{
-  int len = pptr() - pbase();
-  char *txt = new char[len+1];
-  strncpy(txt, pbase(), len);
-  txt[len] = '\0';
-#ifdef __WXMSW__
-  OutputDebugString((LPCSTR)txt);
-#else
-  fprintf(stderr, txt);
-#endif
-  setp(pbase(), epptr());
-  delete[] txt;
-  return EOF;
+    wxRect rect(pos, sz);
+    if (rect.Inside(pt))
+        return win;
+    else
+        return NULL;
 }
 
 }
 
-int wxDebugStreamBuf::sync(void)
+wxWindow* wxGenericFindWindowAtPoint(const wxPoint& pt)
 {
 {
-  int len = pptr() - pbase();
-  char *txt = new char[len+1];
-  strncpy(txt, pbase(), len);
-  txt[len] = '\0';
-#ifdef __WXMSW__
-  OutputDebugString((LPCSTR)txt);
-#else
-  fprintf(stderr, txt);
-#endif
-  setp(pbase(), epptr());
-  delete[] txt;
-  return 0;
+    // Go backwards through the list since windows
+    // on top are likely to have been appended most
+    // recently.
+    wxNode* node = wxTopLevelWindows.Last();
+    while (node)
+    {
+        wxWindow* win = (wxWindow*) node->Data();
+        wxWindow* found = wxFindWindowAtPoint(win, pt);
+        if (found)
+            return found;
+        node = node->Previous();
+    }
+    return NULL;
 }
 
 }
 
-#endif
+#endif // wxUSE_GUI
 
 /*
 On Fri, 21 Jul 1995, Paul Craven wrote:
 
 /*
 On Fri, 21 Jul 1995, Paul Craven wrote:
@@ -586,12 +615,12 @@ On Fri, 21 Jul 1995, Paul Craven wrote:
 > Is there a way to find the path of running program's executable? I can get
 > my home directory, and the current directory, but I don't know how to get the
 > executable directory.
 > Is there a way to find the path of running program's executable? I can get
 > my home directory, and the current directory, but I don't know how to get the
 > executable directory.
-> 
+>
 
 The code below (warty as it is), does what you want on most Unix,
 DOS, and Mac platforms (it's from the ALS Prolog main).
 
 
 The code below (warty as it is), does what you want on most Unix,
 DOS, and Mac platforms (it's from the ALS Prolog main).
 
-|| Ken Bowen      Applied Logic Systems, Inc.         PO Box 180,     
+|| Ken Bowen      Applied Logic Systems, Inc.         PO Box 180,
 ||====            Voice:  +1 (617)965-9191            Newton Centre,
 ||                FAX:    +1 (617)965-1636            MA  02159  USA
                   Email:  ken@als.com        WWW: http://www.als.com
 ||====            Voice:  +1 (617)965-9191            Newton Centre,
 ||                FAX:    +1 (617)965-1636            MA  02159  USA
                   Email:  ken@als.com        WWW: http://www.als.com
@@ -604,8 +633,8 @@ DOS, and Mac platforms (it's from the ALS Prolog main).
 
 /*--------------------------------------------------------------------*
  | whereami is given a filename f in the form:  whereami(argv[0])
 
 /*--------------------------------------------------------------------*
  | whereami is given a filename f in the form:  whereami(argv[0])
- | It returns the directory in which the executable file (containing 
- | this code [main.c] ) may be found.  A dot will be returned to indicate 
+ | It returns the directory in which the executable file (containing
+ | this code [main.c] ) may be found.  A dot will be returned to indicate
  | the current directory.
  *--------------------------------------------------------------------*/
 
  | the current directory.
  *--------------------------------------------------------------------*/
 
@@ -613,7 +642,7 @@ static void
 whereami(name)
     char *name;
 {
 whereami(name)
     char *name;
 {
-    register char *cutoff = NULL;      /* stifle -Wall */
+    register char *cutoff = NULL;        /* stifle -Wall */
     register char *s;
     register char *t;
     int   cc;
     register char *s;
     register char *t;
     int   cc;
@@ -626,117 +655,117 @@ whereami(name)
 
     if (access(name, R_OK) == 0) {
 
 
     if (access(name, R_OK) == 0) {
 
-       /*-------------------------------------------------------------*
-        * The file was accessible without any other work.  But the current
-        * working directory might change on us, so if it was accessible
-        * through the cwd, then we should get it for later accesses.
-        *-------------------------------------------------------------*/
+        /*-------------------------------------------------------------*
+         * The file was accessible without any other work.  But the current
+         * working directory might change on us, so if it was accessible
+         * through the cwd, then we should get it for later accesses.
+         *-------------------------------------------------------------*/
 
 
-       t = imagedir;
-       if (!absolute_pathname(name)) {
-#if defined(DOS) || defined(__WIN32__)
-           int   drive;
-           char *newrbuf;
+        t = imagedir;
+        if (!absolute_pathname(name)) {
+#if defined(__DOS__) || defined(__WIN32__)
+            int   drive;
+            char *newrbuf;
 
 
-           newrbuf = imagedir;
+            newrbuf = imagedir;
 #ifndef __DJGPP__
 #ifndef __DJGPP__
-           if (*(name + 1) == ':') {
-               if (*name >= 'a' && *name <= 'z')
-                   drive = (int) (*name - 'a' + 1);
-               else
-                   drive = (int) (*name - 'A' + 1);
-               *newrbuf++ = *name;
-               *newrbuf++ = *(name + 1);
-               *newrbuf++ = DIR_SEPARATOR;
-           }
-           else {
-               drive = 0;
-               *newrbuf++ = DIR_SEPARATOR;
-           }
-           if (getcwd(newrbuf, drive) == 0) {  /* } */
+            if (*(name + 1) == ':') {
+                if (*name >= 'a' && *name <= 'z')
+                    drive = (int) (*name - 'a' + 1);
+                else
+                    drive = (int) (*name - 'A' + 1);
+                *newrbuf++ = *name;
+                *newrbuf++ = *(name + 1);
+                *newrbuf++ = DIR_SEPARATOR;
+            }
+            else {
+                drive = 0;
+                *newrbuf++ = DIR_SEPARATOR;
+            }
+            if (getcwd(newrbuf, drive) == 0) {        /* } */
 #else
 #else
-           if (getcwd(newrbuf, 1024) == 0) {   /* } */
+            if (getcwd(newrbuf, 1024) == 0) {        /* } */
 #endif
 #else  /* DOS */
 #ifdef HAVE_GETWD
 #endif
 #else  /* DOS */
 #ifdef HAVE_GETWD
-           if (getwd(imagedir) == 0) {         /* } */
+            if (getwd(imagedir) == 0) {                /* } */
 #else  /* !HAVE_GETWD */
 #else  /* !HAVE_GETWD */
-           if (getcwd(imagedir, 1024) == 0) {
+            if (getcwd(imagedir, 1024) == 0) {
 #endif /* !HAVE_GETWD */
 #endif /* DOS */
 #endif /* !HAVE_GETWD */
 #endif /* DOS */
-               fatal_error(FE_GETCWD, 0);
-           }
-           for (; *t; t++)     /* Set t to end of buffer */
-               ;
-           if (*(t - 1) == DIR_SEPARATOR)      /* leave slash if already
-                                                * last char
-                                                */
-               cutoff = t - 1;
-           else {
-               cutoff = t;     /* otherwise put one in */
-               *t++ = DIR_SEPARATOR;
-           }
-       }
+                fatal_error(FE_GETCWD, 0);
+            }
+            for (; *t; t++)        /* Set t to end of buffer */
+                ;
+            if (*(t - 1) == DIR_SEPARATOR)        /* leave slash if already
+                                                 * last char
+                                                 */
+                cutoff = t - 1;
+            else {
+                cutoff = t;        /* otherwise put one in */
+                *t++ = DIR_SEPARATOR;
+            }
+        }
 #if (!defined(__MAC__) && !defined(__DJGPP__) && !defined(__GO32__) && !defined(__WIN32__))
 #if (!defined(__MAC__) && !defined(__DJGPP__) && !defined(__GO32__) && !defined(__WIN32__))
-       else
-               (*t++ = DIR_SEPARATOR);
+        else
+                (*t++ = DIR_SEPARATOR);
 #endif
 
 #endif
 
-       /*-------------------------------------------------------------*
-        * Copy the rest of the string and set the cutoff if it was not
-        * already set.  If the first character of name is a slash, cutoff
-        * is not presently set but will be on the first iteration of the
-        * loop below.
-        *-------------------------------------------------------------*/
+        /*-------------------------------------------------------------*
+         * Copy the rest of the string and set the cutoff if it was not
+         * already set.  If the first character of name is a slash, cutoff
+         * is not presently set but will be on the first iteration of the
+         * loop below.
+         *-------------------------------------------------------------*/
 
 
-       for ((*name == DIR_SEPARATOR ? (s = name+1) : (s = name));;) {
-           if (*s == DIR_SEPARATOR)
-                       cutoff = t;
-           if (!(*t++ = *s++))
-                       break;
-       }
+        for ((*name == DIR_SEPARATOR ? (s = name+1) : (s = name));;) {
+            if (*s == DIR_SEPARATOR)
+                        cutoff = t;
+            if (!(*t++ = *s++))
+                        break;
+        }
 
     }
     else {
 
 
     }
     else {
 
-       /*-------------------------------------------------------------*
-        * Get the path list from the environment.  If the path list is
-        * inaccessible for any reason, leave with fatal error.
-        *-------------------------------------------------------------*/
+        /*-------------------------------------------------------------*
+         * Get the path list from the environment.  If the path list is
+         * inaccessible for any reason, leave with fatal error.
+         *-------------------------------------------------------------*/
 
 #ifdef __MAC__
 
 #ifdef __MAC__
-       if ((s = getenv("Commands")) == (char *) 0)
+        if ((s = getenv("Commands")) == (char *) 0)
 #else
 #else
-       if ((s = getenv("PATH")) == (char *) 0)
+        if ((s = getenv("PATH")) == (char *) 0)
 #endif
 #endif
-           fatal_error(FE_PATH, 0);
-
-       /*
-        * Copy path list into ebuf and set the source pointer to the
-        * beginning of this buffer.
-        */
-
-       strcpy(ebuf, s);
-       s = ebuf;
-
-       for (;;) {
-           t = imagedir;
-           while (*s && *s != PATH_SEPARATOR)
-               *t++ = *s++;
-           if (t > imagedir && *(t - 1) == DIR_SEPARATOR) 
-               ;               /* do nothing -- slash already is in place */
-           else
-               *t++ = DIR_SEPARATOR;   /* put in the slash */
-           cutoff = t - 1;     /* set cutoff */
-           strcpy(t, name);
-           if (access(imagedir, R_OK) == 0)
-               break;
-
-           if (*s)
-               s++;            /* advance source pointer */
-           else
-               fatal_error(FE_INFND, 0);
-       }
+            fatal_error(FE_PATH, 0);
+
+        /*
+         * Copy path list into ebuf and set the source pointer to the
+         * beginning of this buffer.
+         */
+
+        strcpy(ebuf, s);
+        s = ebuf;
+
+        for (;;) {
+            t = imagedir;
+            while (*s && *s != PATH_SEPARATOR)
+                *t++ = *s++;
+            if (t > imagedir && *(t - 1) == DIR_SEPARATOR)
+                ;                /* do nothing -- slash already is in place */
+            else
+                *t++ = DIR_SEPARATOR;        /* put in the slash */
+            cutoff = t - 1;        /* set cutoff */
+            strcpy(t, name);
+            if (access(imagedir, R_OK) == 0)
+                break;
+
+            if (*s)
+                s++;                /* advance source pointer */
+            else
+                fatal_error(FE_INFND, 0);
+        }
 
     }
 
 
     }
 
@@ -749,35 +778,43 @@ whereami(name)
 
 #ifdef HAVE_SYMLINK
     while ((cc = readlink(imagedir, ebuf, 512)) != -1) {
 
 #ifdef HAVE_SYMLINK
     while ((cc = readlink(imagedir, ebuf, 512)) != -1) {
-       ebuf[cc] = 0;
-       s = ebuf;
-       if (*s == DIR_SEPARATOR) {
-           t = imagedir;
-       }
-       else {
-           t = cutoff + 1;
-       }
-       for (;;) {
-           if (*s == DIR_SEPARATOR)
-               cutoff = t;     /* mark the last slash seen */
-           if (!(*t++ = *s++)) /* copy the character */
-               break;
-       }
+        ebuf[cc] = 0;
+        s = ebuf;
+        if (*s == DIR_SEPARATOR) {
+            t = imagedir;
+        }
+        else {
+            t = cutoff + 1;
+        }
+        for (;;) {
+            if (*s == DIR_SEPARATOR)
+                cutoff = t;        /* mark the last slash seen */
+            if (!(*t++ = *s++))        /* copy the character */
+                break;
+        }
     }
 
 #endif /* HAVE_SYMLINK */
 
     }
 
 #endif /* HAVE_SYMLINK */
 
-    strcpy(imagename, cutoff + 1);     /* keep the image name */
-    *(cutoff + 1) = 0;         /* chop off the filename part */
+    strcpy(imagename, cutoff + 1);        /* keep the image name */
+    *(cutoff + 1) = 0;                /* chop off the filename part */
 }
 
 #endif
 
 }
 
 #endif
 
+#if wxUSE_GUI
+
+// ----------------------------------------------------------------------------
+// GUI helpers
+// ----------------------------------------------------------------------------
+
 /*
  * N.B. these convenience functions must be separate from msgdlgg.cpp, textdlgg.cpp
  * since otherwise the generic code may be pulled in unnecessarily.
  */
 
 /*
  * N.B. these convenience functions must be separate from msgdlgg.cpp, textdlgg.cpp
  * since otherwise the generic code may be pulled in unnecessarily.
  */
 
+#if wxUSE_MSGDLG
+
 int wxMessageBox(const wxString& message, const wxString& caption, long style,
                  wxWindow *parent, int WXUNUSED(x), int WXUNUSED(y) )
 {
 int wxMessageBox(const wxString& message, const wxString& caption, long style,
                  wxWindow *parent, int WXUNUSED(x), int WXUNUSED(y) )
 {
@@ -788,40 +825,472 @@ int wxMessageBox(const wxString& message, const wxString& caption, long style,
     {
         case wxID_OK:
             return wxOK;
     {
         case wxID_OK:
             return wxOK;
-            break;
         case wxID_YES:
             return wxYES;
         case wxID_YES:
             return wxYES;
-            break;
         case wxID_NO:
             return wxNO;
         case wxID_NO:
             return wxNO;
-            break;
-        default:
         case wxID_CANCEL:
             return wxCANCEL;
         case wxID_CANCEL:
             return wxCANCEL;
-            break;
     }
     }
-    return ans;
+
+    wxFAIL_MSG( _T("unexpected return code from wxMessageDialog") );
+
+    return wxCANCEL;
 }
 
 }
 
+#endif // wxUSE_MSGDLG
+
+#if wxUSE_TEXTDLG
+
 wxString wxGetTextFromUser(const wxString& message, const wxString& caption,
                         const wxString& defaultValue, wxWindow *parent,
                         int x, int y, bool WXUNUSED(centre) )
 {
 wxString wxGetTextFromUser(const wxString& message, const wxString& caption,
                         const wxString& defaultValue, wxWindow *parent,
                         int x, int y, bool WXUNUSED(centre) )
 {
+    wxString str;
     wxTextEntryDialog dialog(parent, message, caption, defaultValue, wxOK|wxCANCEL, wxPoint(x, y));
     if (dialog.ShowModal() == wxID_OK)
     wxTextEntryDialog dialog(parent, message, caption, defaultValue, wxOK|wxCANCEL, wxPoint(x, y));
     if (dialog.ShowModal() == wxID_OK)
-        return dialog.GetValue();
-    else
-        return wxString("");
+    {
+        str = dialog.GetValue();
+    }
+
+    return str;
 }
 
 }
 
+wxString wxGetPasswordFromUser(const wxString& message,
+                               const wxString& caption,
+                               const wxString& defaultValue,
+                               wxWindow *parent)
+{
+    wxString str;
+    wxTextEntryDialog dialog(parent, message, caption, defaultValue,
+                             wxOK | wxCANCEL | wxTE_PASSWORD);
+    if ( dialog.ShowModal() == wxID_OK )
+    {
+        str = dialog.GetValue();
+    }
+
+    return str;
+}
+
+#endif // wxUSE_TEXTDLG
+
+#if wxUSE_COLOURDLG
+
+wxColour wxGetColourFromUser(wxWindow *parent, const wxColour& colInit)
+{
+    wxColourData data;
+    data.SetChooseFull(TRUE);
+    if ( colInit.Ok() )
+    {
+        data.SetColour((wxColour &)colInit); // const_cast
+    }
+
+    wxColour colRet;
+    wxColourDialog dialog(parent, &data);
+    if ( dialog.ShowModal() == wxID_OK )
+    {
+        colRet = dialog.GetColourData().GetColour();
+    }
+    //else: leave it invalid
+
+    return colRet;
+}
+
+#endif // wxUSE_COLOURDLG
+
+#if wxUSE_FONTDLG
+
+wxFont wxGetFontFromUser(wxWindow *parent, const wxFont& fontInit)
+{
+    wxFontData data;
+    if ( fontInit.Ok() )
+    {
+        data.SetInitialFont(fontInit);
+    }
+
+    wxFont fontRet;
+    wxFontDialog dialog(parent, data);
+    if ( dialog.ShowModal() == wxID_OK )
+    {
+        fontRet = dialog.GetFontData().GetChosenFont();
+    }
+    //else: leave it invalid
+
+    return fontRet;
+}
+
+#endif // wxUSE_FONTDLG
+// ----------------------------------------------------------------------------
+// missing C RTL functions (FIXME shouldn't be here at all)
+// ----------------------------------------------------------------------------
+
 #ifdef __MWERKS__
 #ifdef __MWERKS__
-char *strdup(const char *s) 
+#if __MSL__ < 0x7000
+char *strdup(const char *s)
+{
+        return strcpy( (char*) malloc( strlen( s ) + 1 ) , s ) ;
+}
+#endif
+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("WXPREFIX"), &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()
+{
+    static const int maxUserNameLen = 1024; // FIXME arbitrary number
+
+    wxString buf;
+    bool ok = wxGetUserName(buf.GetWriteBuf(maxUserNameLen), maxUserNameLen);
+    buf.UngetWriteBuf();
+
+    if ( !ok )
+        buf.Empty();
+
+    return buf;
+}
+
+wxString wxGetHostName()
+{
+    static const size_t hostnameSize = 257;
+
+    wxString buf;
+    bool ok = wxGetHostName(buf.GetWriteBuf(hostnameSize), hostnameSize);
+
+    buf.UngetWriteBuf();
+
+    if ( !ok )
+        buf.Empty();
+
+    return buf;
+}
+
+wxString wxGetFullHostName()
 {
 {
-       return strcpy( (char*) malloc( strlen( s ) + 1 ) , s ) ;
+    static const size_t hostnameSize = 257;
+
+    wxString buf;
+    bool ok = wxGetFullHostName(buf.GetWriteBuf(hostnameSize), hostnameSize);
+
+    buf.UngetWriteBuf();
+
+    if ( !ok )
+        buf.Empty();
+
+    return buf;
 }
 
 }
 
-int    isascii( int c ) 
+wxString wxGetHomeDir()
 {
 {
-       return ( c >= 0 && c < 128 ) ;
+    wxString home;
+    wxGetHomeDir(&home);
+
+    return home;
 }
 }
+
+#if 0
+
+wxString wxGetCurrentDir()
+{
+    wxString dir;
+    size_t len = 1024;
+    bool ok;
+    do
+    {
+        ok = getcwd(dir.GetWriteBuf(len + 1), len) != NULL;
+        dir.UngetWriteBuf();
+
+        if ( !ok )
+        {
+            if ( errno != ERANGE )
+            {
+                wxLogSysError(_T("Failed to get current directory"));
+
+                return wxEmptyString;
+            }
+            else
+            {
+                // buffer was too small, retry with a larger one
+                len *= 2;
+            }
+        }
+        //else: ok
+    } while ( !ok );
+
+    return dir;
+}
+
+#endif // 0
+
+// ----------------------------------------------------------------------------
+// wxExecute
+// ----------------------------------------------------------------------------
+
+// this is a private function because it hasn't a clean interface: the first
+// array is passed by reference, the second by pointer - instead we have 2
+// public versions of wxExecute() below
+static long wxDoExecuteWithCapture(const wxString& command,
+                                   wxArrayString& output,
+                                   wxArrayString* error)
+{
+#ifdef __WIN16__
+    wxFAIL_MSG("Sorry, this version of wxExecute not implemented on WIN16.");
+
+    return 0;
+#else // !Win16
+    // create a wxProcess which will capture the output
+    wxProcess *process = new wxProcess;
+    process->Redirect();
+
+    long rc = wxExecute(command, wxEXEC_SYNC, process);
+
+#if wxUSE_STREAMS
+    if ( rc != -1 )
+    {
+        wxInputStream* is = process->GetInputStream();
+        wxCHECK_MSG( is, -1, _T("if wxExecute() succeded, stream can't be NULL") );
+        wxTextInputStream tis(*is);
+
+        wxTextInputStream *tes = NULL;
+        wxInputStream *es = NULL;
+        if ( error )
+        {
+            es = process->GetErrorStream();
+
+            wxCHECK_MSG( es, -1, _T("stderr can't be NULL") );
+
+            tes = new wxTextInputStream(*es);
+        }
+
+        bool cont;
+        do
+        {
+            cont = FALSE;
+
+            if ( !is->Eof() && is->IsOk() )
+            {
+                wxString line = tis.ReadLine();
+                if ( is->LastError() )
+                    break;
+
+                cont = TRUE;
+
+                output.Add(line);
+            }
+
+            if ( error && !es->Eof() && es->IsOk() )
+            {
+                wxString line = tes->ReadLine();
+                if ( es->LastError() )
+                    break;
+
+                cont = TRUE;
+
+                error->Add(line);
+            }
+        }
+        while ( cont );
+
+        delete tes;
+    }
+#endif // wxUSE_STREAMS
+
+    delete process;
+
+    return rc;
+#endif // IO redirection supoprted
+}
+
+long wxExecute(const wxString& command, wxArrayString& output)
+{
+    return wxDoExecuteWithCapture(command, output, NULL);
+}
+
+long wxExecute(const wxString& command,
+               wxArrayString& output,
+               wxArrayString& error)
+{
+    return wxDoExecuteWithCapture(command, output, &error);
+}
+
+// ----------------------------------------------------------------------------
+// wxApp::Yield() wrappers for backwards compatibility
+// ----------------------------------------------------------------------------
+
+bool wxYield()
+{
+#if wxUSE_GUI
+    return wxTheApp && wxTheApp->Yield();
+#else
+    return FALSE;
 #endif
 #endif
+}
+
+bool wxYieldIfNeeded()
+{
+#if wxUSE_GUI
+    return wxTheApp && wxTheApp->Yield(TRUE);
+#else
+    return FALSE;
+#endif
+}
+