X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e8fd750b53e1fa51298d8c17495cdac3363841f0..91c536df157aa500e832ff9e8541839d2e07f6b4:/src/os2/utils.cpp diff --git a/src/os2/utils.cpp b/src/os2/utils.cpp index c82dfc9a5a..5ac046f10a 100644 --- a/src/os2/utils.cpp +++ b/src/os2/utils.cpp @@ -24,7 +24,9 @@ #include "wx/intl.h" #include -#include +#ifdef __EMX__ +#include +#endif #include "wx/log.h" @@ -36,14 +38,13 @@ #include #include -#define INCL_DOS -#define INCL_PM -#define INCL_GPI -#include #define PURE_32 + +#ifndef __EMX__ #include #include #include +#endif static const wxChar WX_SECTION[] = _T("wxWindows"); static const wxChar eHOSTNAME[] = _T("HostName"); @@ -65,9 +66,9 @@ bool wxGetHostName( char zServer[256]; char zComputer[256]; unsigned long ulLevel = 0; - unsigned char* zBuffer; - unsigned long ulBuffer; - unsigned long* pulTotalAvail; + unsigned char* zBuffer = NULL; + unsigned long ulBuffer = 256; + unsigned long* pulTotalAvail = NULL; NetBios32GetInfo( (const unsigned char*)zServer ,(const unsigned char*)zComputer @@ -104,10 +105,12 @@ bool wxGetUserId( , int nType ) { +#if defined(__VISAGECPP__) long lrc; // UPM procs return 0 on success lrc = U32ELOCU((unsigned char*)zBuf, (unsigned long *)&nType); if (lrc == 0) return TRUE; +#endif return FALSE; } @@ -128,7 +131,8 @@ bool wxGetUserName( int wxKill( long lPid -, int nSig +, wxSignal eSig +, wxKillError* peError ) { return((int)::DosKillProcess(0, (PID)lPid)); @@ -197,7 +201,7 @@ bool wxShell( // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX) long wxGetFreeMemory() { - void* pMemptr; + void* pMemptr = NULL; ULONG lSize; ULONG lMemFlags; APIRET rc; @@ -209,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; @@ -228,7 +275,7 @@ void wxUsleep( unsigned long ulMilliseconds ) { - ::DosSleep(ulMilliseconds); + ::DosSleep(ulMilliseconds/1000l); } void wxSleep( @@ -244,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 ... @@ -265,6 +314,7 @@ void wxError( , const wxString& rTitle ) { + wxBuffer = new wxChar[256]; wxSprintf(wxBuffer, "%s\nContinue?", WXSTRINGCAST rMsg); if (::WinMessageBox( HWND_DESKTOP ,NULL @@ -273,6 +323,7 @@ void wxError( ,0 ,MB_ICONEXCLAMATION | MB_YESNO ) == MBID_YES) + delete[] wxBuffer; wxExit(); } @@ -294,6 +345,8 @@ void wxFatalError( DosExit(EXIT_PROCESS, ulRc); } +#endif // WXWIN_COMPATIBILITY_2_2 + // Emit a beeeeeep void wxBell() { @@ -334,8 +387,8 @@ bool wxWriteResource( , const wxString& rFile ) { - HAB hab; - HINI hIni; + HAB hab = 0; + HINI hIni = 0; if (rFile != "") { @@ -416,8 +469,8 @@ bool wxGetResource( , const wxString& rFile ) { - HAB hab; - HINI hIni; + HAB hab = 0; + HINI hIni = 0; wxChar zDefunkt[] = _T("$$default"); char zBuf[1000]; @@ -469,6 +522,8 @@ bool wxGetResource( ) { wxChar* zStr = NULL; + + zStr = new wxChar[1000]; bool bSucc = wxGetResource( rSection ,rEntry ,(wxChar **)&zStr @@ -481,7 +536,11 @@ bool wxGetResource( delete[] zStr; return TRUE; } - else return FALSE; + else + { + delete[] zStr; + return FALSE; + } } bool wxGetResource( @@ -492,6 +551,8 @@ bool wxGetResource( ) { wxChar* zStr = NULL; + + zStr = new wxChar[1000]; bool bSucc = wxGetResource( rSection ,rEntry ,(wxChar **)&zStr @@ -504,7 +565,11 @@ bool wxGetResource( delete[] zStr; return TRUE; } - else return FALSE; + else + { + delete[] zStr; + return FALSE; + } } bool wxGetResource( @@ -515,6 +580,8 @@ bool wxGetResource( ) { wxChar* zStr = NULL; + + zStr = new wxChar[1000]; bool bSucc = wxGetResource( rSection ,rEntry ,(wxChar **)&zStr @@ -527,7 +594,11 @@ bool wxGetResource( delete[] zStr; return TRUE; } - else return FALSE; + else + { + delete[] zStr; + return FALSE; + } } #endif // wxUSE_RESOURCES @@ -603,6 +674,8 @@ wxChar* wxGetUserHome ( wxChar* zHome; wxString sUser1(rUser); + wxBuffer = new wxChar[256]; +#ifndef __EMX__ if (sUser1 != _T("")) { wxChar zTmp[64]; @@ -617,20 +690,27 @@ wxChar* wxGetUserHome ( if ((zHome = wxGetenv(_T("TMP"))) != NULL || (zHome = wxGetenv(_T("TMPDIR"))) != NULL || (zHome = wxGetenv(_T("TEMP"))) != NULL) + delete[] wxBuffer; return *zHome ? zHome : (wxChar*)_T("\\"); } if (wxStricmp(zTmp, WXSTRINGCAST sUser1) == 0) sUser1 = _T(""); } } +#endif if (sUser1 == _T("")) + { if ((zHome = wxGetenv(_T("HOME"))) != NULL) { wxStrcpy(wxBuffer, zHome); Unix2DosFilename(wxBuffer); - return wxBuffer; + wxStrcpy(zHome, wxBuffer); + delete[] wxBuffer; + return zHome; } - return NULL; // No home known! + } + delete[] wxBuffer; + return NULL; // No home known! } // Check whether this window wants to process messages, e.g. Stop button @@ -642,8 +722,8 @@ bool wxCheckForInterrupt( if(pWnd) { QMSG vMsg; - HAB hab; - HWND hwndFilter; + HAB hab = 0; + HWND hwndFilter = NULLHANDLE; HWND hwndWin= (HWND) pWnd->GetHWND(); while(::WinPeekMsg(hab, &vMsg, hwndFilter, 0, 0, PM_REMOVE)) @@ -674,6 +754,7 @@ void wxGetMousePosition( // Return TRUE if we have a colour display bool wxColourDisplay() { +#if 0 HPS hpsScreen; HDC hdcScreen; LONG lColors; @@ -682,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 @@ -691,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); } @@ -708,17 +799,64 @@ void wxDisplaySize( int* pWidth , int* pHeight ) +{ + HPS hpsScreen; + HDC hdcScreen; + 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, (PLONG)pWidth); - ::DevQueryCaps(hdcScreen, CAPS_HEIGHT, 1L, (PLONG)pHeight); - DevCloseDC(hdcScreen); + + 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 ) @@ -776,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