+void wxDisplaySizeMM(
+  int*                              pWidth
+, int*                              pHeight
+)
+{
+    HPS                             hpsScreen;
+    HDC                             hdcScreen;
+
+    hpsScreen = ::WinGetScreenPS(HWND_DESKTOP);
+    hdcScreen = ::GpiQueryDevice(hpsScreen);
+
+    if (pWidth)
+        ::DevQueryCaps( hdcScreen
+                       ,CAPS_HORIZONTAL_RESOLUTION
+                       ,1L
+                       ,(PLONG)pWidth
+                      );
+    if (pHeight)
+        ::DevQueryCaps( hdcScreen
+                       ,CAPS_VERTICAL_RESOLUTION
+                       ,1L
+                       ,(PLONG)pHeight
+                      );
+}
+
+void wxClientDisplayRect(int *x, int *y, int *width, int *height)
+{
+    // This is supposed to return desktop dimensions minus any window
+    // manager panels, menus, taskbars, etc.  If there is a way to do that
+    // for this platform please fix this function, otherwise it defaults
+    // to the entire desktop.
+    if (x) *x = 0;
+    if (y) *y = 0;
+    wxDisplaySize(width, height);
+}
+
+
+bool wxDirExists(
+  const wxString&                   rDir
+)
+{
+    return (::DosSetCurrentDir(WXSTRINGCAST rDir));
+}
+
+// ---------------------------------------------------------------------------
+// window information functions
+// ---------------------------------------------------------------------------
+
+wxString WXDLLEXPORT wxGetWindowText(
+  WXHWND                            hWnd
+)
+{
+    wxString                        vStr;
+    long                            lLen = ::WinQueryWindowTextLength((HWND)hWnd) + 1;
+
+    ::WinQueryWindowText((HWND)hWnd, lLen, vStr.GetWriteBuf((int)lLen));
+    vStr.UngetWriteBuf();
+
+    return vStr;
+}
+
+wxString WXDLLEXPORT wxGetWindowClass(
+  WXHWND                            hWnd
+)
+{
+    wxString                        vStr;
+    int                             nLen = 256; // some starting value
+
+    for ( ;; )
+    {
+        int                         nCount = ::WinQueryClassName((HWND)hWnd, nLen, vStr.GetWriteBuf(nLen));
+
+        vStr.UngetWriteBuf();
+        if (nCount == nLen )
+        {
+            // the class name might have been truncated, retry with larger
+            // buffer
+            nLen *= 2;
+        }
+        else
+        {
+            break;
+        }
+    }
+    return vStr;
+}
+
+WXWORD WXDLLEXPORT wxGetWindowId(
+  WXHWND                            hWnd
+)
+{
+    return ::WinQueryWindowUShort((HWND)hWnd, QWS_ID);
+}
+
+wxString WXDLLEXPORT wxPMErrorToStr(
+  ERRORID                           vError
+)
+{
+    wxString                        sError;
+
+    //
+    // Remove the high order byte -- it is useless
+    //
+    vError &= 0x0000ffff;
+    switch(vError)
+    {
+        case PMERR_INVALID_HWND:
+            sError = wxT("Invalid window handle specified");
+            break;
+
+        case PMERR_INVALID_FLAG:
+            sError = wxT("Invalid flag bit set");
+            break;
+
+        case PMERR_NO_MSG_QUEUE:
+            sError = wxT("No message queue available");
+            break;
+
+        case PMERR_INVALID_PARM:
+            sError = wxT("Parameter contained invalid data");
+            break;
+
+        case PMERR_INVALID_PARAMETERS:
+            sError = wxT("Parameter value is out of range");
+            break;
+
+        case PMERR_PARAMETER_OUT_OF_RANGE:
+            sError = wxT("Parameter value is out of range");
+            break;
+
+        case PMERR_INVALID_INTEGER_ATOM:
+            sError = wxT("Not a valid atom");
+            break;
+
+        case PMERR_INVALID_HATOMTBL:
+            sError = wxT("Atom table handle is invalid");
+            break;
+
+        case PMERR_INVALID_ATOM_NAME:
+            sError = wxT("Not a valid atom name");
+            break;
+
+        case PMERR_ATOM_NAME_NOT_FOUND:
+            sError = wxT("Valid name format, but cannot find name in atom table");
+            break;
+
+        default:
+            sError = wxT("Unknown error");
+    }
+    return(sError);
+} // end of wxPMErrorToStr
+
+void wxDrawBorder(
+  HPS                               hPS
+, RECTL&                            rRect
+, WXDWORD                           dwStyle
+)
+{
+    POINTL                          vPoint[2];
+
+    vPoint[0].x = rRect.xLeft;
+    vPoint[0].y = rRect.yBottom;
+    ::GpiMove(hPS, &vPoint[0]);
+    if (dwStyle & wxSIMPLE_BORDER ||
+        dwStyle & wxSTATIC_BORDER)
+    {
+        vPoint[1].x = rRect.xRight - 1;
+        vPoint[1].y = rRect.yTop - 1;
+        ::GpiBox( hPS
+                 ,DRO_OUTLINE
+                 ,&vPoint[1]
+                 ,0L
+                 ,0L
+                );
+    }
+    if (dwStyle & wxSUNKEN_BORDER)
+    {
+        LINEBUNDLE                      vLineBundle;
+
+        vLineBundle.lColor     = 0x00FFFFFF; // WHITE
+        vLineBundle.usMixMode  = FM_OVERPAINT;
+        vLineBundle.fxWidth    = 2;
+        vLineBundle.lGeomWidth = 2;
+        vLineBundle.usType     = LINETYPE_SOLID;
+        vLineBundle.usEnd      = 0;
+        vLineBundle.usJoin     = 0;
+        ::GpiSetAttrs( hPS
+                      ,PRIM_LINE
+                      ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE
+                      ,0L
+                      ,&vLineBundle
+                     );
+        vPoint[1].x = rRect.xRight - 1;
+        vPoint[1].y = rRect.yTop - 1;
+        ::GpiBox( hPS
+                 ,DRO_OUTLINE
+                 ,&vPoint[1]
+                 ,0L
+                 ,0L
+                );
+       vPoint[0].x = rRect.xLeft + 1;
+       vPoint[0].y = rRect.yBottom + 1;
+       ::GpiMove(hPS, &vPoint[0]);
+        vPoint[1].x = rRect.xRight - 2;
+        vPoint[1].y = rRect.yTop - 2;
+        ::GpiBox( hPS
+                 ,DRO_OUTLINE
+                 ,&vPoint[1]
+                 ,0L
+                 ,0L
+                );
+
+        vLineBundle.lColor     = 0x00000000; // BLACK
+        vLineBundle.usMixMode  = FM_OVERPAINT;
+        vLineBundle.fxWidth    = 2;
+        vLineBundle.lGeomWidth = 2;
+        vLineBundle.usType     = LINETYPE_SOLID;
+        vLineBundle.usEnd      = 0;
+        vLineBundle.usJoin     = 0;
+        ::GpiSetAttrs( hPS
+                      ,PRIM_LINE
+                      ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE
+                      ,0L
+                      ,&vLineBundle
+                     );
+        vPoint[0].x = rRect.xLeft + 2;
+        vPoint[0].y = rRect.yBottom + 2;
+        ::GpiMove(hPS, &vPoint[0]);
+        vPoint[1].x = rRect.xLeft + 2;
+        vPoint[1].y = rRect.yTop - 3;
+        ::GpiLine(hPS, &vPoint[1]);
+        vPoint[1].x = rRect.xRight - 3;
+        vPoint[1].y = rRect.yTop - 3;
+        ::GpiLine(hPS, &vPoint[1]);
+
+        vPoint[0].x = rRect.xLeft + 3;
+        vPoint[0].y = rRect.yBottom + 3;
+        ::GpiMove(hPS, &vPoint[0]);
+        vPoint[1].x = rRect.xLeft + 3;
+        vPoint[1].y = rRect.yTop - 4;
+        ::GpiLine(hPS, &vPoint[1]);
+        vPoint[1].x = rRect.xRight - 4;
+        vPoint[1].y = rRect.yTop - 4;
+        ::GpiLine(hPS, &vPoint[1]);
+    }
+    if (dwStyle & wxDOUBLE_BORDER)
+    {
+        LINEBUNDLE                      vLineBundle;
+
+        vLineBundle.lColor     = 0x00FFFFFF; // WHITE
+        vLineBundle.usMixMode  = FM_OVERPAINT;
+        vLineBundle.fxWidth    = 2;
+        vLineBundle.lGeomWidth = 2;
+        vLineBundle.usType     = LINETYPE_SOLID;
+        vLineBundle.usEnd      = 0;
+        vLineBundle.usJoin     = 0;
+        ::GpiSetAttrs( hPS
+                      ,PRIM_LINE
+                      ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE
+                      ,0L
+                      ,&vLineBundle
+                     );
+        vPoint[1].x = rRect.xRight - 1;
+        vPoint[1].y = rRect.yTop - 1;
+        ::GpiBox( hPS
+                 ,DRO_OUTLINE
+                 ,&vPoint[1]
+                 ,0L
+                 ,0L
+                );
+        vLineBundle.lColor     = 0x00000000; // WHITE
+        vLineBundle.usMixMode  = FM_OVERPAINT;
+        vLineBundle.fxWidth    = 2;
+        vLineBundle.lGeomWidth = 2;
+        vLineBundle.usType     = LINETYPE_SOLID;
+        vLineBundle.usEnd      = 0;
+        vLineBundle.usJoin     = 0;
+        ::GpiSetAttrs( hPS
+                      ,PRIM_LINE
+                      ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE
+                      ,0L
+                      ,&vLineBundle
+                     );
+        vPoint[0].x = rRect.xLeft + 2;
+        vPoint[0].y = rRect.yBottom + 2;
+        ::GpiMove(hPS, &vPoint[0]);
+        vPoint[1].x = rRect.xRight - 2;
+        vPoint[1].y = rRect.yTop - 2;
+        ::GpiBox( hPS
+                 ,DRO_OUTLINE
+                 ,&vPoint[1]
+                 ,0L
+                 ,0L
+                );
+        vLineBundle.lColor     = 0x00FFFFFF; // BLACK
+        vLineBundle.usMixMode  = FM_OVERPAINT;
+        vLineBundle.fxWidth    = 2;
+        vLineBundle.lGeomWidth = 2;
+        vLineBundle.usType     = LINETYPE_SOLID;
+        vLineBundle.usEnd      = 0;
+        vLineBundle.usJoin     = 0;
+        ::GpiSetAttrs( hPS
+                      ,PRIM_LINE
+                      ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE
+                      ,0L
+                      ,&vLineBundle
+                     );
+        vPoint[0].x = rRect.xLeft + 3;
+        vPoint[0].y = rRect.yBottom + 3;
+        ::GpiMove(hPS, &vPoint[0]);
+        vPoint[1].x = rRect.xRight - 3;
+        vPoint[1].y = rRect.yTop - 3;
+        ::GpiBox( hPS
+                 ,DRO_OUTLINE
+                 ,&vPoint[1]
+                 ,0L
+                 ,0L
+                );
+    }
+    if (dwStyle & wxRAISED_BORDER)
+    {
+        LINEBUNDLE                      vLineBundle;
+
+        vLineBundle.lColor     = 0x00000000; // BLACK
+        vLineBundle.usMixMode  = FM_OVERPAINT;
+        vLineBundle.fxWidth    = 2;
+        vLineBundle.lGeomWidth = 2;
+        vLineBundle.usType     = LINETYPE_SOLID;
+        vLineBundle.usEnd      = 0;
+        vLineBundle.usJoin     = 0;
+        ::GpiSetAttrs( hPS
+                      ,PRIM_LINE
+                      ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE
+                      ,0L
+                      ,&vLineBundle
+                     );
+        vPoint[1].x = rRect.xRight - 1;
+        vPoint[1].y = rRect.yTop - 1;
+        ::GpiBox( hPS
+                 ,DRO_OUTLINE
+                 ,&vPoint[1]
+                 ,0L
+                 ,0L
+                );
+       vPoint[0].x = rRect.xLeft + 1;
+       vPoint[0].y = rRect.yBottom + 1;
+       ::GpiMove(hPS, &vPoint[0]);
+        vPoint[1].x = rRect.xRight - 2;
+        vPoint[1].y = rRect.yTop - 2;
+        ::GpiBox( hPS
+                 ,DRO_OUTLINE
+                 ,&vPoint[1]
+                 ,0L
+                 ,0L
+                );
+
+        vLineBundle.lColor     = 0x00FFFFFF; // WHITE
+        vLineBundle.usMixMode  = FM_OVERPAINT;
+        vLineBundle.fxWidth    = 2;
+        vLineBundle.lGeomWidth = 2;
+        vLineBundle.usType     = LINETYPE_SOLID;
+        vLineBundle.usEnd      = 0;
+        vLineBundle.usJoin     = 0;
+        ::GpiSetAttrs( hPS
+                      ,PRIM_LINE
+                      ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE
+                      ,0L
+                      ,&vLineBundle
+                     );
+        vPoint[0].x = rRect.xLeft + 2;
+        vPoint[0].y = rRect.yBottom + 2;
+        ::GpiMove(hPS, &vPoint[0]);
+        vPoint[1].x = rRect.xLeft + 2;
+        vPoint[1].y = rRect.yTop - 3;
+        ::GpiLine(hPS, &vPoint[1]);
+        vPoint[1].x = rRect.xRight - 3;
+        vPoint[1].y = rRect.yTop - 3;
+        ::GpiLine(hPS, &vPoint[1]);
+
+        vPoint[0].x = rRect.xLeft + 3;
+        vPoint[0].y = rRect.yBottom + 3;
+        ::GpiMove(hPS, &vPoint[0]);
+        vPoint[1].x = rRect.xLeft + 3;
+        vPoint[1].y = rRect.yTop - 4;
+        ::GpiLine(hPS, &vPoint[1]);
+        vPoint[1].x = rRect.xRight - 4;
+        vPoint[1].y = rRect.yTop - 4;
+        ::GpiLine(hPS, &vPoint[1]);
+    }
+} // end of wxDrawBorder
+