]> git.saurik.com Git - wxWidgets.git/blobdiff - src/os2/utils.cpp
Added wxBufferedDC class.
[wxWidgets.git] / src / os2 / utils.cpp
index 34cb8a977f85db24a84c0ffadf90f58ac64ee2de..5ac046f10a676010e9ed48875589bfb90594b303 100644 (file)
@@ -26,8 +26,6 @@
 #include <ctype.h>
 #ifdef __EMX__
 #include <dirent.h>
-#else
-#include <direct.h>
 #endif
 
 #include "wx/log.h"
 #include <errno.h>
 #include <stdarg.h>
 
-#define INCL_DOS
-#define INCL_PM
-#define INCL_GPI
-#include <os2.h>
 #define PURE_32
+
 #ifndef __EMX__
 #include <upm.h>
 #include <netcons.h>
@@ -110,7 +105,7 @@ bool wxGetUserId(
 , int                               nType
 )
 {
-#ifndef __EMX__
+#if defined(__VISAGECPP__)
     long                            lrc;
     // UPM procs return 0 on success
     lrc = U32ELOCU((unsigned char*)zBuf, (unsigned long *)&nType);
@@ -136,7 +131,8 @@ bool wxGetUserName(
 
 int wxKill(
   long                              lPid
-, int                               nSig
+, wxSignal                          eSig
+, wxKillError*                      peError
 )
 {
     return((int)::DosKillProcess(0, (PID)lPid));
@@ -217,6 +213,49 @@ long wxGetFreeMemory()
     return (long)lSize;
 }
 
+// ----------------------------------------------------------------------------
+// env vars
+// ----------------------------------------------------------------------------
+
+bool wxGetEnv(const wxString& var, wxString *value)
+{
+    // wxGetenv is defined as getenv()
+    wxChar *p = wxGetenv(var);
+    if ( !p )
+        return FALSE;
+
+    if ( value )
+    {
+        *value = p;
+    }
+
+    return TRUE;
+}
+
+bool wxSetEnv(const wxString& variable, const wxChar *value)
+{
+#if defined(HAVE_SETENV)
+    return setenv(variable.mb_str(), value ? wxString(value).mb_str().data()
+                                           : NULL, 1 /* overwrite */) == 0;
+#elif defined(HAVE_PUTENV)
+    wxString s = variable;
+    if ( value )
+        s << _T('=') << value;
+
+    // transform to ANSI
+    const char *p = s.mb_str();
+
+    // the string will be free()d by libc
+    char *buf = (char *)malloc(strlen(p) + 1);
+    strcpy(buf, p);
+
+    return putenv(buf) == 0;
+#else // no way to set an env var
+    return FALSE;
+#endif
+}
+
+
 // Sleep for nSecs seconds. Attempt a Windows implementation using timers.
 static bool inTimer = FALSE;
 
@@ -236,7 +275,7 @@ void wxUsleep(
   unsigned long                     ulMilliseconds
 )
 {
-    ::DosSleep(ulMilliseconds);
+    ::DosSleep(ulMilliseconds/1000l);
 }
 
 void wxSleep(
@@ -252,6 +291,8 @@ void wxFlushEvents()
 //  wxYield();
 }
 
+#if WXWIN_COMPATIBILITY_2_2
+
 // Output a debug mess., in a system dependent fashion.
 void wxDebugMsg(
   const wxChar*                     zFmt ...
@@ -304,6 +345,8 @@ void wxFatalError(
     DosExit(EXIT_PROCESS, ulRc);
 }
 
+#endif // WXWIN_COMPATIBILITY_2_2
+
 // Emit a beeeeeep
 void wxBell()
 {
@@ -711,6 +754,7 @@ void wxGetMousePosition(
 // Return TRUE if we have a colour display
 bool wxColourDisplay()
 {
+#if 0
     HPS                             hpsScreen;
     HDC                             hdcScreen;
     LONG                            lColors;
@@ -719,6 +763,11 @@ bool wxColourDisplay()
     hdcScreen = ::GpiQueryDevice(hpsScreen);
     ::DevQueryCaps(hdcScreen, CAPS_COLORS, 1L, &lColors);
     return(lColors > 1L);
+#else
+    // I don't see how the PM display could not be color. Besides, this
+    // was leaking DCs and PSs!!!  MN
+    return TRUE;
+#endif
 }
 
 // Returns depth of screen
@@ -728,15 +777,20 @@ int wxDisplayDepth()
     HDC                             hdcScreen;
     LONG                            lPlanes;
     LONG                            lBitsPerPixel;
-    LONG                            nDepth;
-
-    hpsScreen = ::WinGetScreenPS(HWND_DESKTOP);
-    hdcScreen = ::GpiQueryDevice(hpsScreen);
-    ::DevQueryCaps(hdcScreen, CAPS_COLOR_PLANES, 1L, &lPlanes);
-    ::DevQueryCaps(hdcScreen, CAPS_COLOR_BITCOUNT, 1L, &lBitsPerPixel);
-
-    nDepth = (int)(lPlanes * lBitsPerPixel);
-    DevCloseDC(hdcScreen);
+    static LONG                     nDepth = 0;
+
+    // The screen colordepth ain't gonna change. No reason to query
+    // it over and over!
+    if (!nDepth) {
+        hpsScreen = ::WinGetScreenPS(HWND_DESKTOP);
+        hdcScreen = ::GpiQueryDevice(hpsScreen);
+        ::DevQueryCaps(hdcScreen, CAPS_COLOR_PLANES, 1L, &lPlanes);
+        ::DevQueryCaps(hdcScreen, CAPS_COLOR_BITCOUNT, 1L, &lBitsPerPixel);
+
+        nDepth = (int)(lPlanes * lBitsPerPixel);
+        ::DevCloseDC(hdcScreen);
+        ::WinReleasePS(hpsScreen);
+    }
     return (nDepth);
 }
 
@@ -748,18 +802,61 @@ void wxDisplaySize(
 {
     HPS                             hpsScreen;
     HDC                             hdcScreen;
-    LONG                            lWidth;
-    LONG                            lHeight;
+    static LONG                     lWidth  = 0;
+    static LONG                     lHeight = 0;
+
+    // The screen size ain't gonna change either so just cache the values
+    if (!lWidth) {
+        hpsScreen = ::WinGetScreenPS(HWND_DESKTOP);
+        hdcScreen = ::GpiQueryDevice(hpsScreen);
+        ::DevQueryCaps(hdcScreen, CAPS_WIDTH, 1L, &lWidth);
+        ::DevQueryCaps(hdcScreen, CAPS_HEIGHT, 1L, &lHeight);
+        ::DevCloseDC(hdcScreen);
+        ::WinReleasePS(hpsScreen);
+    }
+    *pWidth = (int)lWidth;
+    *pHeight = (int)lHeight;
+}
+
+void wxDisplaySizeMM(
+  int*                              pWidth
+, int*                              pHeight
+)
+{
+    HPS                             hpsScreen;
+    HDC                             hdcScreen;
 
     hpsScreen = ::WinGetScreenPS(HWND_DESKTOP);
     hdcScreen = ::GpiQueryDevice(hpsScreen);
-    ::DevQueryCaps(hdcScreen, CAPS_WIDTH, 1L, &lWidth);
-    ::DevQueryCaps(hdcScreen, CAPS_HEIGHT, 1L, &lHeight);
-    DevCloseDC(hdcScreen);
-    *pWidth = (int)lWidth;
-    *pHeight = (int)lHeight;
+
+    if (pWidth)
+        ::DevQueryCaps( hdcScreen
+                       ,CAPS_HORIZONTAL_RESOLUTION
+                       ,1L
+                       ,(PLONG)pWidth
+                      );
+    if (pHeight)
+        ::DevQueryCaps( hdcScreen
+                       ,CAPS_VERTICAL_RESOLUTION
+                       ,1L
+                       ,(PLONG)pHeight
+                      );
+    ::DevCloseDC(hdcScreen);
+    ::WinReleasePS(hpsScreen);
 }
 
+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
 )
@@ -817,3 +914,385 @@ WXWORD WXDLLEXPORT wxGetWindowId(
     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
+
+void wxOS2SetFont(
+  HWND                              hWnd
+, const wxFont&                     rFont
+)
+{
+    char                            zFont[128];
+    char                            zFacename[30];
+    char                            zWeight[30];
+    char                            zStyle[30];
+
+    if (hWnd == NULLHANDLE)
+        return;
+
+    //
+    // The fonts available for Presentation Params are just three
+    // outline fonts, the rest are available to the GPI, so we must
+    // map the families to one of these three
+    //
+    switch(rFont.GetFamily())
+    {
+        case wxSCRIPT:
+            strcpy(zFacename, "Script");
+            break;
+
+        case wxDECORATIVE:
+        case wxROMAN:
+            strcpy(zFacename,"Tms Rmn");
+            break;
+
+        case wxTELETYPE:
+            strcpy(zFacename, "Courier");
+            break;
+
+        case wxMODERN:
+            strcpy(zFacename, "System VIO");
+            break;
+
+        case wxSWISS:
+            strcpy(zFacename, "Helv");
+            break;
+
+        case wxDEFAULT:
+        default:
+            strcpy(zFacename, "System VIO");
+            break;
+    }
+
+    switch(rFont.GetWeight())
+    {
+        default:
+        case wxNORMAL:
+        case wxLIGHT:
+            zWeight[0] = '\0';
+            break;
+
+        case wxBOLD:
+        case wxFONTWEIGHT_MAX:
+            strcpy(zWeight, "Bold");
+            break;
+    }
+
+    switch(rFont.GetStyle())
+    {
+        case wxITALIC:
+        case wxSLANT:
+            strcpy(zStyle, "Italic");
+            break;
+
+        default:
+            zStyle[0] = '\0';
+            break;
+    }
+    sprintf(zFont, "%d.%s", rFont.GetPointSize(), zFacename);
+    if (zWeight[0] != '\0')
+    {
+        strcat(zFont, " ");
+        strcat(zFont, zWeight);
+    }
+    if (zStyle[0] != '\0')
+    {
+        strcat(zFont, " ");
+        strcat(zFont, zStyle);
+    }
+    ::WinSetPresParam(hWnd, PP_FONTNAMESIZE, strlen(zFont) + 1, (PVOID)zFont);
+} // end of wxOS2SetFont